package com.yxinsur.imc.business.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yxinsur.imc.business.domain.*;
import com.yxinsur.imc.business.enums.ChargeIntervalEnum;
import com.yxinsur.imc.business.enums.IsDeletedEnum;
import com.yxinsur.imc.business.enums.YesOrNoEnum;
import com.yxinsur.imc.business.form.OrderRiskForm;
import com.yxinsur.imc.business.form.PrerenewalCreateForm;
import com.yxinsur.imc.business.form.PrerenewalForm;
import com.yxinsur.imc.business.form.RealConfirmForm;
import com.yxinsur.imc.business.mapper.*;
import com.yxinsur.imc.business.service.IImcInsRateService;
import com.yxinsur.imc.business.service.IImcPrerenewalService;
import com.yxinsur.imc.business.vo.OrderRiskRateVo;
import com.yxinsur.imc.business.vo.PrerenewalVo;
import com.yxinsur.imc.business.vo.RealConfirmVo;
import com.yxinsur.imc.common.exception.BusinessException;
import com.yxinsur.imc.common.utils.DateUtils;
import com.yxinsur.imc.common.utils.SecurityUtils;
import com.yxinsur.imc.common.utils.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 待导入续期主Service业务层处理
 *
 * @author imc
 * @date 2021-05-26
 */
@Service
public class ImcPrerenewalServiceImpl extends ServiceImpl<ImcPrerenewalMapper, ImcPrerenewal> implements IImcPrerenewalService
{
    private static final Logger logger = LoggerFactory.getLogger(ImcPrerenewalServiceImpl.class);

    @Autowired
    private ImcPrerenewalMapper imcPrerenewalMapper;
    @Autowired
    private ImcPrerenewalDetailMapper imcPrerenewalDetailMapper;
    @Autowired
    private ImcOrderRiskMapper imcOrderRiskMapper;
    @Autowired
    private ImcOrderMapper imcOrderMapper;
    @Autowired
    private IImcInsRateService imcInsRateService;
    @Autowired
    private ImcRepoInsMapper imcRepoInsMapper;
    /**
     * 查询待导入续期主列表
     *
     * @param prerenewalForm 待导入续期主
     * @return 待导入续期主
     */
    @Override
    public List<PrerenewalVo> selectImcPrerenewalList(PrerenewalForm prerenewalForm)
    {
        logger.info("待导入续期主列表分页查询，参数：{}",prerenewalForm.toString());
        return imcPrerenewalMapper.selectImcPrerenewalList(SecurityUtils.getTenantId(),prerenewalForm);
    }

    /**
     * 生成续期数据
     *
     * @param prerenewalCreateForm 待导入续期主
     * @return 结果
     */
    @Override
    @Transactional
    public int createPrerenewalData(PrerenewalCreateForm prerenewalCreateForm) {
        logger.info("生成续期数据，参数：{}",prerenewalCreateForm.toString());
        //基本数据
        Date date = DateUtils.getNowDate();
        String username = SecurityUtils.getUsername();
        Long tenantId = SecurityUtils.getTenantId();

        QueryWrapper<ImcPrerenewal> prerenewalQueryWrapper = new QueryWrapper<>();
        prerenewalQueryWrapper.eq("renewal_month",prerenewalCreateForm.getRenewalMonth());
        prerenewalQueryWrapper.eq("org_id",prerenewalCreateForm.getOrgId());
        prerenewalQueryWrapper.eq("is_deleted",IsDeletedEnum.N.getCode());
        prerenewalQueryWrapper.eq("tenant_id",tenantId);
        if(this.imcPrerenewalMapper.selectCount(prerenewalQueryWrapper) > 0){
            throw new BusinessException("当前机构"+prerenewalCreateForm.getRenewalMonth()+"月份的续期数据已生成过，请勿反复生成");
        }
        //保存主表信息
        ImcPrerenewal prerenewal = new ImcPrerenewal();
        BeanUtils.copyProperties(prerenewalCreateForm,prerenewal);
        prerenewal.setIsImported(YesOrNoEnum.N.name());
        prerenewal.setIsCanceled(YesOrNoEnum.N.name());
        prerenewal.setCreateId(username);
        prerenewal.setCreateTime(date);
        prerenewal.setIsDeleted(IsDeletedEnum.N.getCode());
        prerenewal.setTenantId(tenantId);
        this.imcPrerenewalMapper.insert(prerenewal);

        if(StringUtils.isNotBlank(prerenewalCreateForm.getRenewalMonth())){
            prerenewalCreateForm.setRenewalMonth(prerenewalCreateForm.getRenewalMonth()+"-01");//补充为完整日期
        }
        Date renewalDate = DateUtils.parseDate(prerenewalCreateForm.getRenewalMonth());
        //年缴续期数据查询
        List<ImcPrerenewalDetail> yearRenewalList  = this.imcPrerenewalDetailMapper.selectYearIntervalOrderData(prerenewalCreateForm);
        //非年续期数据查询
        List<ImcPrerenewalDetail> nonYearRenewalList = this.imcPrerenewalDetailMapper.selectMonthIntervalOrderData(prerenewalCreateForm);
        ArrayList<ImcPrerenewalDetail> prerenewalDetails = new ArrayList<>();
        //年缴续期数据处理
        for (ImcPrerenewalDetail detail : yearRenewalList) {
            if(StringUtils.isNotBlank(detail.getChargeIntervalEnum())){
                ChargeIntervalEnum charge = ChargeIntervalEnum.getByKName(detail.getChargeIntervalEnum());
                //一年缴费次数获取
                int chargeInYear = ChargeIntervalEnum.getByKName(detail.getChargeIntervalEnum()).getPayNum();
                //生效日期至所选月份相差的月份数
                int month = DateUtils.getDifMonth(detail.getEffectiveDate(),renewalDate);
                if(month%charge.getPayMonth() ==0){
                    detail.setPolicyYear((int)month/12+1l);
                    detail.setPayNum((int)month/12+1l);
                    if(detail.getPayNum() <= chargeInYear*Integer.valueOf(detail.getChargePeriodValue())) {
                        prerenewalDetails.add(detail);
                    }
                }
            }
        }
        //非年续期数据处理
        for(ImcPrerenewalDetail detail:nonYearRenewalList){
            if(StringUtils.isNotBlank(detail.getChargeIntervalEnum())){
                ChargeIntervalEnum charge = ChargeIntervalEnum.getByKName(detail.getChargeIntervalEnum());
                //一年缴费次数获取
                int chargeInYear = ChargeIntervalEnum.getByKName(detail.getChargeIntervalEnum()).getPayNum();
                //生效日期至所选月份相差的月份数
                int month = DateUtils.getDifMonth(detail.getEffectiveDate(),renewalDate);
                if(month%charge.getPayMonth() ==0){
                    detail.setPolicyYear((int)month/12+1l);
                    detail.setPayNum(month/charge.getPayMonth()+1l);
                    if(detail.getPayNum() <= chargeInYear*Integer.valueOf(detail.getChargePeriodValue())) {
                        prerenewalDetails.add(detail);
                    }
                }
            }
        }
        for (ImcPrerenewalDetail detail:prerenewalDetails) {
            ImcOrder order = this.imcOrderMapper.selectById(detail.getOrderId());
            //费率查询
            OrderRiskForm riskForm = new OrderRiskForm();
            riskForm.setInputOrgId(order.getSettleOrgId());
            riskForm.setRepoInsId(detail.getRepoInsId());
            riskForm.setChargePeriodValue(detail.getChargePeriodValue());
            riskForm.setCoveragePeriodValue(detail.getCoveragePeriodValue());
            riskForm.setApplyDate(detail.getApplyDate());
            riskForm.setChargeIntervalEnum(detail.getChargeIntervalEnum());
            riskForm.setPensionAge(detail.getPensionAge());
            riskForm.setInsSchemeId(detail.getInsSchemeId());
            riskForm.setFactor1Value(detail.getFactor1Value());
            riskForm.setFactor2Value(detail.getFactor2Value());
            riskForm.setFactor3Value(detail.getFactor3Value());
            riskForm.setPolicyYear(detail.getPolicyYear());
            OrderRiskRateVo vo = this.imcInsRateService.getRates(riskForm);
            if(!vo.isHasStandRate() || !vo.isHasCommissionRate()){
                throw new BusinessException("获取不到折标率或佣金率，请检查费率配信息");
            }
            detail.setStandRate(vo.getStandRate());
            detail.setCommissionRate(vo.getCommissionRate());
            detail.setFeeRate(vo.getFeeRate());
            detail.setSupplierStandRate(vo.getSupplierStandRate());
            detail.setYearScale(vo.getYearScale());

            detail.setPrerenewalId(prerenewal.getId());
            detail.setCreateId(username);
            detail.setCreateTime(date);
            detail.setIsDeleted(IsDeletedEnum.N.getCode());
            detail.setTenantId(tenantId);
            this.imcPrerenewalDetailMapper.insert(detail);
        }
        return yearRenewalList.size();
    }

    /**
     * 确认导入到order_risk
     *
     * @param id 批次ID
     * @return 结果
     */
    @Override
    @Transactional
    public int confirmImportData(Long id) {
        logger.info("确认导入续期数据，批次号：{}",id);
        List<ImcPrerenewalDetail> list = this.getDetailList(id);
        Date date = DateUtils.getNowDate();
        String username = SecurityUtils.getUsername();
        Long tenantId = SecurityUtils.getTenantId();
        StringBuffer errorStr = new StringBuffer();
        for (ImcPrerenewalDetail detail:list) {
            if(detail.getCommissionRate() == null){
                ImcOrder order = this.imcOrderMapper.selectById(detail.getOrderId());
                errorStr.append("</br>保单号："+order.getPolicyCode()+"的数据未匹配到对应的续期佣金率，请完善费率后重新抽挡");
            }
            ImcOrderRisk risk = new ImcOrderRisk();
            BeanUtils.copyProperties(detail,risk);
            risk.setId(null);
            risk.setCreateId(username);
            risk.setCreateTime(date);
            risk.setIsDeleted(IsDeletedEnum.N.getCode());
            risk.setTenantId(tenantId);
            this.imcOrderRiskMapper.insert(risk);

            detail.setOrderRiskId(risk.getId());
            detail.setUpdateId(username);
            detail.setUpdateTime(date);
            this.imcPrerenewalDetailMapper.updateById(detail);

            if(errorStr.length()>0){
                throw new BusinessException(errorStr.toString());
            }
        }
        ImcPrerenewal prerenewal = this.imcPrerenewalMapper.selectById(id);
        prerenewal.setIsImported(YesOrNoEnum.Y.name());
        prerenewal.setIsCanceled(YesOrNoEnum.N.name());
        this.imcPrerenewalMapper.updateById(prerenewal);
        return list.size();
    }

    /**
     * 按批次撤销导入
     *
     * @param id 批次ID
     * @return 结果
     */
    @Override
    @Transactional
    public int cancelConfirm(Long id) {
        logger.info("确认撤销续期数据，批次号：{}",id);
        List<ImcPrerenewalDetail> list = this.getDetailList(id);
        Date date = DateUtils.getNowDate();
        String username = SecurityUtils.getUsername();
        Long tenantId = SecurityUtils.getTenantId();
        int total = 0;//统计撤销成功条数
        for (ImcPrerenewalDetail detail:list) {
            if(detail.getOrderRiskId() != null){
                ImcOrderRisk risk = this.imcOrderRiskMapper.selectById(detail.getOrderRiskId());
                risk.setIsDeleted(String.valueOf(risk.getId()));
                risk.setUpdateId(username);
                risk.setUpdateTime(date);
                total += this.imcOrderRiskMapper.updateById(risk);
            }
        }
        ImcPrerenewal prerenewal = this.imcPrerenewalMapper.selectById(id);
        prerenewal.setIsCanceled(YesOrNoEnum.Y.name());
        prerenewal.setIsImported(YesOrNoEnum.N.name());
        this.imcPrerenewalMapper.updateById(prerenewal);
        return total;
    }

    /**
     * 移除数据
     *
     * @param id 批次ID
     * @return 结果
     */
    @Override
    public int removeData(Long id) {
        logger.info("确认删除续期数据，批次号：{}",id);
        List<ImcPrerenewalDetail> list = this.getDetailList(id);
        Date date = DateUtils.getNowDate();
        String username = SecurityUtils.getUsername();
        for (ImcPrerenewalDetail detail:list) {
            detail.setIsDeleted(detail.getId());
            detail.setUpdateTime(date);
            detail.setUpdateId(username);
            this.imcPrerenewalDetailMapper.updateById(detail);
        }
        ImcPrerenewal prerenewal = this.imcPrerenewalMapper.selectById(id);
        prerenewal.setIsDeleted(prerenewal.getId());
        prerenewal.setUpdateTime(date);
        prerenewal.setUpdateId(username);
        return this.imcPrerenewalMapper.updateById(prerenewal);
    }

    /**
     * 实收确认
     * @param realConfirmForm
     * @return
     */
    @Override
    public int realConfirm(RealConfirmForm realConfirmForm) {
        Long orderRiskId = realConfirmForm.getOrderRiskId();
        ImcOrderRisk imcOrderRisk = new ImcOrderRisk();
        imcOrderRisk.setId(orderRiskId);
        imcOrderRisk.setYearScale(realConfirmForm.getYearScale());
        imcOrderRisk.setCommissionRate(realConfirmForm.getCommissionRate());
        imcOrderRisk.setStandRate(realConfirmForm.getStandRate());
        imcOrderRisk.setSupplierStandRate(realConfirmForm.getSupplierStandRate());
        imcOrderRisk.setPaymentDate(realConfirmForm.getPaymentDate());
        imcOrderRisk.setPaymentPrem(realConfirmForm.getPaymentPrem());
        return imcOrderRiskMapper.updateById(imcOrderRisk);
    }

    /**
     * 查询费率参数
     * @param realConfirmForm
     * @return
     */
    @Override
    public RealConfirmVo realGetRates(RealConfirmForm realConfirmForm) {
        Long orderRiskId = realConfirmForm.getOrderRiskId();
        ImcOrderRisk risk = imcOrderRiskMapper.selectById(orderRiskId);
        ImcRepoIns imcRepoIns = imcRepoInsMapper.getImcRepoInsByInsCode(risk.getInsCode(),realConfirmForm.getSupplierId());
        //校验有效时间时间
        Date checkDate = risk.getInsureDate()==null?risk.getApplyDate():risk.getInsureDate();
        OrderRiskForm riskForm = new OrderRiskForm();
        BeanUtils.copyProperties(risk,riskForm);
        riskForm.setApplyDate(checkDate);
        riskForm.setRepoInsId(imcRepoIns.getId());
        riskForm.setInputOrgId(realConfirmForm.getOrgId());
        risk.setPensionAge(risk.getPensionAge());
        OrderRiskRateVo rates = imcInsRateService.getRates(riskForm);
        RealConfirmVo realConfirmVo = new RealConfirmVo();
        realConfirmVo.setStandRate(rates.getStandRate());
        realConfirmVo.setCommissionRate(rates.getCommissionRate());
        realConfirmVo.setYearScale(rates.getYearScale());
        realConfirmVo.setSupplierStandRate(rates.getSupplierStandRate());
        realConfirmVo.setOrderRiskForm(riskForm);
        return realConfirmVo;
    }

    //获取生成的详情数据
    public List<ImcPrerenewalDetail> getDetailList(Long prerenewalId) {
        QueryWrapper<ImcPrerenewalDetail> detailQueryWrapper = new QueryWrapper<>();
        detailQueryWrapper.eq("prerenewal_id",prerenewalId);
        detailQueryWrapper.eq("is_deleted",IsDeletedEnum.N.getCode());
        detailQueryWrapper.eq("tenant_id",SecurityUtils.getTenantId());
        return this.imcPrerenewalDetailMapper.selectList(detailQueryWrapper);
    }
}
